Option Explicit

' ==================================================
' 可配置属性
' ==================================================
' ==============================
' 其他属性
' ==============================
' 用来标识表物理名的标题内容
' 用来在生成 sheet 中的所有 table 的 sql 时，定位一个 table 的开始位置
Public tablePhyNameTitleContent As String

' ==============================
' 行号、列号
' ==============================
' 表物理名所在行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
Public tablePhyNameRowNo As Integer

' table 的列物理名行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
Public columnPhyNameRowNo As Integer

' table 的列逻辑名行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
Public columnLogicNameRowNo As Integer

' table 的列类型行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
Public columnTypeRowNo As Integer

' table 的列数据长度行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
Public columnSizeRowNo As Integer

' table 的第一个数据行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
Public dataStartRowNo As Integer

' 在 sheet 中，每个 table 的起始标题列的列号(从 1 开始，这里是 table 起始位置开始计算的行号)
' 不是第一列 table 的数据所在的列，而是声明标题每一行的内容类型的那一列
'
' 扫描数据时，将会从这个列的下一列开始扫描
Public defineTitleColNo As Integer

' ==============================
' 数据生成处理器
' ==============================
' 自定义数据生成处理器集合
Private customColDataCreatorHandlerList As Collection

' 默认数据生成处理器集合
Private defaultColDataCreatorHandlerList As Collection

' 兜底的数据生成处理器
Private fbColDataCreatorHandler As IColDataCreatorHandler

' ======================================================================
' 构造器
' ======================================================================
Private Sub Class_Initialize()
    ' 用来标识表名的标题内容
    tablePhyNameTitleContent = "tableName"
    ' 表物理名所在行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
    tablePhyNameRowNo = 1
    ' table 的列物理名行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
    columnPhyNameRowNo = 3
    ' table 的列逻辑名行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
    columnLogicNameRowNo = 2
    ' table 的列类型行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
    columnTypeRowNo = 4
    ' table 的列数据长度行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
    columnSizeRowNo = 5
    ' table 的第一个数据行的行号(从 1 开始，这里是 table 起始位置开始计算的行号)
    dataStartRowNo = 7
    ' 在 sheet 中，每个 table 的起始标题列的列号
    defineTitleColNo = 3

    ' 初始化: 默认数据生成处理器集合
    Set defaultColDataCreatorHandlerList = New Collection

    Dim strHanlder As StringColDataCreatorHandler
    Set strHanlder = New StringColDataCreatorHandler
    defaultColDataCreatorHandlerList.Add strHanlder

    Dim intHanlder As IntColDataCreatorHandler
    Set intHanlder = New IntColDataCreatorHandler
    defaultColDataCreatorHandlerList.Add intHanlder

    Dim decimalHanlder As DecimalColDataCreatorHandler
    Set decimalHanlder = New DecimalColDataCreatorHandler
    defaultColDataCreatorHandlerList.Add decimalHanlder

    Dim timestampHanlder As TimestampColDataCreatorHandler
    Set timestampHanlder = New TimestampColDataCreatorHandler
    defaultColDataCreatorHandlerList.Add timestampHanlder

End Sub

' ======================================================================
' 配置方法
' ======================================================================
' 添加兜底的数据生成处理器
' 注意:
'   如果参数 `handler` 是 `Nothing`，将会立刻结束
'
' @param handler 自定义数据生成处理器
Public Sub adddFullbackHandler(ByRef handler As IColDataCreatorHandler)
    ' 1. 检查: 如果参数 handler 是 Nothing，则立刻结束
    If handler Is Nothing Then
        Exit Sub
    End If

    ' 2. 保存处理器
    Set fbColDataCreatorHandler = handler
End Sub

' 添加自定义数据生成处理器
' 注意:
'   如果参数 `handler` 是 `Nothing`，将会立刻结束
'
' @param handler 自定义数据生成处理器
Public Sub addHandler(ByRef handler As IColDataCreatorHandler)
    ' 1. 检查: 如果参数 handler 是 Nothing，则立刻结束
    If handler Is Nothing Then
        Exit Sub
    End If

    ' 2. 检查: 如果自定义数据生成处理器集合为空，则创建 (这里表示第一次调用该方法来添加自定义处理器)
    If customColDataCreatorHandlerList Is Nothing Then
        Set customColDataCreatorHandlerList = New Collection
    End If

    ' 3. 保存自定义处理器
    customColDataCreatorHandlerList.Add handler
End Sub

' ======================================================================
' 生成 table 的随机数据
' ======================================================================
' 依照区域内的 table 定义，为每个 table 生成指定数量的随机数据
' 如果没设置参数 dataRangeStr，则将会按照各项配置扫描 `sh` 中的所有表格，并为每个表格分别生成随机数据
' 如果设置了参数 dataRangeStr，并且参数是一个单元格，则将会以这个单元格为表格的起始位置开始向下扫描数据，并生成随机数据
' 如果设置了参数 dataRangeStr，并且参数是一个大的区域，则将会以这个区域的起始位置为表格的起始位置，扫描整个区域的数据，并生成随机数据
'
' @param sh 保存了 table 定义的 Worksheet
' @param dataCount 每个表需要生成的数据数量
' @optional-param dataRangeStr 被选中的区域
Public Sub createSimpleRandomData(ByRef sh As Worksheet, ByRef dataCount As Integer, Optional dataRangeStr As String = "")
    ' ==================================================
    ' 1. 检查参数
    ' ==================================================
    ' 1. 检查: 如果 `dataCount < 0`，则立刻结束
    If dataCount < 0 Then
        Exit Sub
    End If

    ' ==================================================
    ' 2. 初始化边界
    ' ==================================================
    ' 扫描时需要的定义标题列的列号
    Dim scanDefineTitleColNo As Integer
    ' 扫描的起始行号
    Dim scanStartRowNo As Long
    ' 扫描的结束行号
    Dim scanEndRowNo As Long
    ' 扫描的结束列号: `scanEndColNo`
    Dim scanEndColNo As Integer

    If dataRangeStr = "" Then
        ' 2. 如果未设置参数 `dataRangeStr`
        ' 2.1. `scanDefineTitleColNo` 设置为类属性 `defineTitleColNo`
        scanDefineTitleColNo = defineTitleColNo
        ' 2.2. `scanStartRowNo` 设置为 `defineTitleColNo` 列中被使用的第一行的行号
        scanStartRowNo = UtilsWorksheet.getColFirstUsedRowNo(sh, defineTitleColNo)
        ' 2.3. `scanEndRowNo` 设置为 `sh` 中被使用的最后一行的行号
        scanEndRowNo = UtilsWorksheet.getUsedRangeEndRowNo(sh)
        ' 2.4. `scanEndColNo` 设置为 `sh` 中被使用的最后一列的列号
        scanEndColNo = UtilsWorksheet.getUsedRangeEndColumnNo(sh)
    Else
        ' 获取数据区域
        Dim dataRange As Range
        Set dataRange = UtilsWorksheet.getRangeByStr(sh, dataRangeStr)

        If dataRange.Count = 1 Then
            ' 3. 如果 `dataRangeStr` 是一个单元格
            ' 3.1. `scanDefineTitleColNo` 设置为 `dataRangeStr` 的前一列
            scanDefineTitleColNo = dataRange.Column - 1
            ' 3.2. `scanStartRowNo` 设置为 `dataRangeStr` 的行号
            scanStartRowNo = dataRange.Row
            ' 3.3. `scanEndRowNo` 设置为 `sh` 中被使用的最后一行的行号
            scanEndRowNo = UtilsWorksheet.getUsedRangeEndRowNo(sh)
            ' 3.4. `scanEndColNo` 设置为 `sh` 中被使用的最后一列的列号
            scanEndColNo = UtilsWorksheet.getUsedRangeEndColumnNo(sh)
        Else
            ' 4. 如果 `dataRangeStr` 是一个大的区域
            ' 4.1. `scanDefineTitleColNo` 设置为 `dataRangeStr` 的前一列
            scanDefineTitleColNo = dataRange.Column - 1
            ' 4.2. `scanStartRowNo` 设置为 `dataRangeStr` 的起始行号
            scanStartRowNo = dataRange.Row
            ' 4.3. `scanEndRowNo` 设置为 `dataRangeStr` 的结束行号
            scanEndRowNo = UtilsWorksheet.getRangeLastRowNo(dataRange)
            ' 4.4. `scanEndColNo` 设置为 `dataRangeStr` 的结束列号
            scanEndColNo = UtilsWorksheet.getRangeLastColNo(dataRange)
        End If
    End If

    ' ==================================================
    ' 3. 初始化变量
    ' ==================================================
    ' 1. 设置行号变量 `ri = scanStartRowNo`
    Dim ri As Long

    ' 2. 设置 table 定义的起始列号 `tableStartColNo = scanDefineTitleColNo + 1`
    Dim tableStartColNo As Integer
    tableStartColNo = scanDefineTitleColNo + 1

    ' 3. table 的起始行号 `tableStartRowNo As Long`
    Dim tableStartRowNo As Long

    ' 4. table 区域的结束行号 `tableEndRowNo As Long`
    Dim tableEndRowNo As Long

    ' 5. 新插入的行数 `insertedRowCount As Long`
    Dim insertedRowCount As Long

    ' ==================================================
    ' 4. 扫描第一个 table 的起始位置
    ' ==================================================
    ' 1. 从 `scanStartRowNo` 开始，扫描下一个 table 定义开始时的行号，保存到 `tableStartRowNo`
    tableStartRowNo = findNextTableStartRowNo(sh, scanStartRowNo, scanEndRowNo, scanDefineTitleColNo)
    ' 2. 检查: 如果 `tableStartRowNo == -1`(没有找到 table)，则立刻结束
    If tableStartRowNo = -1 Then
        Exit Sub
    End If

    ' ==================================================
    ' 5. 遍历每一个 table 定义并生成数据
    ' ==================================================
    ' 1. 从 `ri = tableStartRowNo + 1` 开始遍历，直到 `scanEndRowNo`
    ri = tableStartRowNo + 1
    While ri <= scanEndRowNo
        ' 2. 扫描下两个 table 定义开始时的行号，保存到 `ri`。如果没有找到，则退出遍历
        ri = findNextTableStartRowNo(sh, ri, scanEndRowNo, scanDefineTitleColNo)

        ' 3. 生成从 `tableStartRowNo` 开始的这个 table 的随机数据，将返回的 table 结束区域行号保存到 `tableEndRowNo`
        '    下边界的行号为 `ri - 1`
        tableEndRowNo = doCreateTableRandomData(sh, tableStartRowNo, tableStartColNo, scanEndColNo, dataCount, (ri - 1))

        ' 4. 检查: 如果 `ri == -1`，则说明当前已经是最后一个表了，则结束
        If ri = -1 Then
            Exit Sub
        End If

        ' 5. 计算新插入的行数
        ' 5.1. 检查: 如果 `tableEndRowNo < ri`，则设置 `insertedRowCount = 0`
        If tableEndRowNo < ri Then
            insertedRowCount = 0
        Else
        ' 5.2. 否则: 设置 `insertedRowCount = tableEndRowNo - ri + 1`
            insertedRowCount = tableEndRowNo - ri + 1
        End If

        ' 6. 扫描的结束行行号 `scanEndRowNo` 向后移动 `insertedRowCount` 行
        scanEndRowNo = scanEndRowNo + insertedRowCount

        ' 7. 设置 `tableStartRowNo = ri + insertedRowCount`，保存下一轮遍历中需要使用的 table 的起始位置
        tableStartRowNo = ri + insertedRowCount

        ' 8. 设置 `ri = tableStartRowNo + 1`，即将 `ri` 移动到 table 的起始位置之后，以便找到下一个 table
        ri = tableStartRowNo + 1

        ' 9. 回到 2 继续遍历
    Wend

End Sub

' 生成随机数据
' @param sh
' @param ri table 的起始行号
' @param tableStartColNo table 定义的起始列号
' @param scanEndColNo 扫描 table 时的结束行号
' @param dataCount` 需要生成的数据行数
' @param bottomBoundaryRowNo 底部的边界行号，表示超过这个行号之后就是下一个 table 了
' @return table 区域的结束行号，并且这个行号的下一行就是下一个 table 的起始位置
Private Function doCreateTableRandomData(ByRef sh As workSheet, _
    ByRef ri As Long, _
    ByRef tableStartColNo As Integer, _
    ByRef scanEndColNo As Integer, _
    ByRef dataCount As Integer, _
    ByRef bottomBoundaryRowNo As Long) As Long
    ' ==================================================
    ' 1. 初始化变量
    ' ==================================================
    ' 1. 设置列号变量 `ci As Integer`
    Dim ci As Integer
    ' 2. table 的数据起始行行号: `tableDataStartRowNo As Long`
    Dim tableDataStartRowNo As Long
    ' 3. table 列数据类型行的行号: `tableColTypeRowNo As Long`
    Dim tableColTypeRowNo As Long
    ' 4. table 列数据长度行的行号: `tableColSizeRowNo As Long`
    Dim tableColSizeRowNo As Long
    ' 5. table 列物理名行的行号: `tableColPhyNameRowNo As Long`
    Dim tableColPhyNameRowNo As Long
    ' 6. table 列逻辑名行的行号: `tableColLogicNameRowNo As Long`
    Dim tableColLogicNameRowNo As Long
    ' 7. 列类型字符串 `colTypeStr As String`
    Dim colTypeStr As String
    ' 8. 列长度字符串 `colSizeStr As String`
    Dim colSizeStr As String
    ' 9. 列物理名字符串 `colPhyNameStr As String`
    Dim colPhyNameStr As String
    ' 10. 列逻辑名字符串 `colLogicNameStr As String`
    Dim colLogicNameStr As String
    ' 11. 生成随机数据时，用来记录正在生成的行数 `i As Integer`
    Dim i As Integer
    ' 12. table 物理名 `tablePhyName As String`
    Dim tablePhyName As String
    ' 13. 数据生成处理器 `colDataCreatorHandler As IColDataCreatorHandler`
    Dim colDataCreatorHandler As IColDataCreatorHandler

    ' ==================================================
    ' 2. 设置各变量的值
    ' ==================================================
    ' 1. table 的数据起始行行号: `tableDataStartRowNo = ri + dataStartRowNo - 1`
    tableDataStartRowNo = ri + dataStartRowNo - 1
    ' 2. table 列数据类型行行号: `tableColTypeRowNo = ri + columnTypeRowNo - 1`
    tableColTypeRowNo = ri + columnTypeRowNo - 1
    ' 3. table 列数据长度行的行号: `tableColSizeRowNo = ri + columnSizeRowNo - 1`
    tableColSizeRowNo = ri + columnSizeRowNo - 1
    ' 4. table 列物理名行的行号: `tableColPhyNameRowNo = ri + columnPhyNameRowNo - 1`
    tableColPhyNameRowNo = ri + columnPhyNameRowNo - 1
    ' 5. table 列逻辑名行的行号: `tableColLogicNameRowNo = ri + columnLogicNameRowNo - 1`
    tableColLogicNameRowNo = ri + columnLogicNameRowNo - 1
    ' 6. 获取表名 `tablePhyName = (ri + tablePhyNameRowNo - 1, tableStartColNo)`
    tablePhyName = Trim(sh.Cells(ri + tablePhyNameRowNo - 1, tableStartColNo))

    ' ==================================================
    ' 3. 清理插入数据的空间
    ' ==================================================
    ' 1. 从数据起始行 `tableDataStartRowNo` 开始，尝试向下插入 `dataCount + 2` 行
    doCreateTableRandomData = UtilsWorksheet.tryInsertTextRowToDown(sh, tableDataStartRowNo, dataCount + 2, bottomBoundaryRowNo)

    ' 2. 清除 `result` 到 `bottomBoundaryRowNo` 之间的内容
    ' 2.1. 检查: 如果 `result < bottomBoundaryRowNo`，则继续执行 2
    If doCreateTableRandomData < bottomBoundaryRowNo Then
        ' 2.2. 将 `result + 1` 到 `bottomBoundaryRowNo` 之间的行全部清空，并设置格式为文本
        UtilsWorksheet.clearRangeAndToText sh.Rows((doCreateTableRandomData + 1) & ":" & bottomBoundaryRowNo)

        ' 2.3. 设置 `result = bottomBoundaryRowNo` （保存为 table 空间的结束行号）
        doCreateTableRandomData = bottomBoundaryRowNo
    End If

    With sh
    ' ==================================================
    ' 4. 遍历这个表定义的每一列
    ' ==================================================
        ' 1. 从 `ci = tableStartColNo` 列开始遍历，直到 `scanEndColNo`
        For ci = tableStartColNo To scanEndColNo
            ' 2. 获取列类型字符串 `colTypeStr = (tableColTypeRowNo, ci)`
            colTypeStr = Trim(.Cells(tableColTypeRowNo, ci))
            ' 3. 检查: 如果 `colTypeStr == ""`，则退出这一级遍历
            '      这里表示当前的 table 的随机数据已经生成完了
            If colTypeStr = "" Then
                Exit For
            End If

            ' 4. 获取列长度字符串 `colSizeStr = (tableColSizeRowNo, ci)`
            colSizeStr = Trim(.Cells(tableColSizeRowNo, ci))

            ' 5. 获取列的物理名 `colPhyNameStr = (tableColPhyNameRowNo, ci)`
            colPhyNameStr = Trim(.Cells(tableColPhyNameRowNo, ci))

            ' 6. 获取列的逻辑名 `colLogicNameStr = (tableColLogicNameRowNo, ci)`
            colLogicNameStr = Trim(.Cells(tableColLogicNameRowNo, ci))

            ' 7. 使用列信息来获取一个数据生成处理器 `colDataCreatorHandler`
            Set colDataCreatorHandler = findColDataCreatorHandler(tablePhyName, _
                colTypeStr, colSizeStr, _
                colPhyNameStr, colLogicNameStr)

            ' 8. 生成随机数据
            ' 8.1 从 `i = 0` 开始，遍历到 `dataCount - 1` 位置，生成每一行的数据
            For i = 0 To dataCount - 1
                ' 8.2. 生成一个随机数据，并保存到 `(tableDataStartRowNo + i, ci)`
                .Cells(tableDataStartRowNo + i, ci).Value = colDataCreatorHandler.createRandomData
            Next
        Next

    ' ==================================================
    ' 5. 设置数据空间的格式
    ' ==================================================
        ' 1. 检查: 如果: `(ci - 1) >= tableStartColNo`，则执行后续处理
        If (ci - 1) >= tableStartColNo Then
            ' 2. 为从 `tableDataStartRowNo` 到 `tableDataStartRowNo + dataCount - 1` 的行、从 `tableStartColNo` 到 `ci - 1` 的列设置边框线
            UtilsWorksheet.setRangeAllDefaultBorders .Range( _
                .Cells(tableDataStartRowNo, tableStartColNo), _
                .Cells(tableDataStartRowNo + dataCount - 1, ci - 1))
        End If
    End With

    ' ==================================================
    ' 6. 结束
    ' ==================================================
    ' 1. 返回: table 区域的结束行号 `result`
    ' doCreateTableRandomData = result
    ' return doCreateTableRandomData
End Function

' 获取一个数据生成处理器
' @param tablePhyName table 物理名字符串
' @param colTypeStr 列类型字符串
' @param colSizeStr 列长度字符串
' @param colPhyNameStr 列的物理名
' @param colLogicNameStr 列的逻辑名
Private Function findColDataCreatorHandler(ByRef tablePhyName As String, _
    ByRef colTypeStr As String, ByRef colSizeStr As String, _
    ByRef colPhyNameStr As String, ByRef colLogicNameStr As String) As IColDataCreatorHandler

    ' ==================================================
    ' 1. 声明变量
    ' ==================================================
    ' 1. 列的类型 `colType As String`
    Dim colType As String
    ' 2. 列的数据长度 `colMainSize As Integer`
    Dim colMainSize As Integer
    ' 3. 列数据的小数长度 `colScaleSize As Integer`
    Dim colScaleSize As Integer
    ' 4. 索引 `i As Integer`
    Dim i As Integer
    ' 5. 临时数据生成处理器 `handler As IColDataCreatorHandler`
    Dim handler As IColDataCreatorHandler

    ' ==================================================
    ' 2. 初始化变量
    ' ==================================================
    ' 1. 确认这个列的 DB 数据类型 `dbType = UtilsDBTable.analyzeTypeName`
    colType = UtilsDBTable.analyzeTypeName(colTypeStr, colSizeStr)
    ' 2. 获取列数据的长度 与 小数长度
    ' 2.1. 从 `colSizeStr` 列长度字符串中获取 `,` 的位置到 `i`
    i = InStr(colSizeStr, ",")

    ' 2.2. 检查: 如果 `,` 的索引 `i == 0`，则说明没有逗号
    If i = 0 Then
        ' 设置数据长度 `colMainSize = colSizeStr`
        colMainSize = Val(colSizeStr)
        ' 设置小数长度为 0 `colScaleSize = 0`
        colScaleSize = 0
    ' 2.3. 否则
    Else
        ' 截取数据长度 `colMainSize = colSizeStr(0, i - 1)`
        colMainSize = Val(Left(colSizeStr, i - 1))
        ' 截取小数长度 `colScaleSize = colSizeStr(i + 1)`
        colScaleSize = Val(Right(colSizeStr, Len(colSizeStr) - i))
    End If

    ' ==================================================
    ' 3. 在自定义数据生成处理器集合中搜索
    ' ==================================================
    ' 1. 检查: 如果自定义数据生成处理器集合为空，则跳过当前处理
    If Not customColDataCreatorHandlerList Is Nothing Then
        ' 2. 从 `i = 1` 开始遍历到 `customColDataCreatorHandlerList.Count`
        For i = 1 To customColDataCreatorHandlerList.Count
            ' 3. 获取第 `i` 个数据生成处理器到 `handler`
            Set handler = customColDataCreatorHandlerList.Item(i)

            ' 4. 检查: 如果这里处理器适用: `handler#handle`
            If handler.handle(tablePhyName, colLogicNameStr, colPhyNameStr, colType, colMainSize, colScaleSize) Then
                ' 4.1. 将列信息保存到 handler
                handler.saveColDefine tablePhyName, colLogicNameStr, colPhyNameStr, colType, colMainSize, colScaleSize

                ' 4.2. 结束，并返回 handler
                Set findColDataCreatorHandler = handler
                Exit Function
            End If

            ' 5. 否则，回到 3 继续遍历
        Next
    End If

    ' ==================================================
    ' 4. 在默认数据生成处理器集合中搜索
    ' ==================================================
    ' 1. 从 `i = 1` 开始遍历到 `defaultColDataCreatorHandlerList.Count`
    For i = 1 To defaultColDataCreatorHandlerList.Count
        ' 2. 获取第 `i` 个数据生成处理器到 `handler`
        Set handler = defaultColDataCreatorHandlerList.Item(i)

        ' 3. 检查: 如果这里处理器适用: `handler#handle`
        If handler.handle(tablePhyName, colLogicNameStr, colPhyNameStr, colType, colMainSize, colScaleSize) Then
            ' 3.1. 将列信息保存到 handler
            handler.saveColDefine tablePhyName, colLogicNameStr, colPhyNameStr, colType, colMainSize, colScaleSize

            ' 3.2. 结束，并返回 handler
            Set findColDataCreatorHandler = handler
            Exit Function
        End If

        ' 4. 否则，回到 2 继续遍历
    Next

    ' ==================================================
    ' 5. 到这里说明没有匹配到任何处理器，则返回兜底的处理器
    ' ==================================================
    ' 1. 检查: 如果 `fbColDataCreatorHandler` 是空，则创建一个 `FullbackColDataCreatorHandler` 类型的对象，并保存
    If fbColDataCreatorHandler Is Nothing Then
        Dim fb As FullbackColDataCreatorHandler
        Set fb = New FullbackColDataCreatorHandler
        Set fbColDataCreatorHandler = fb
    End If

    ' 2. 将列信息保存到 `fbColDataCreatorHandler`
    fbColDataCreatorHandler.saveColDefine tablePhyName, colLogicNameStr, colPhyNameStr, colType, colMainSize, colScaleSize

    ' 3. 结束，并返回 `fbColDataCreatorHandler`
    Set findColDataCreatorHandler = fbColDataCreatorHandler

End Function

' 搜索下一个表的起始行号
' 如果已经没有 table 了，则返回 -1
Private Function findNextTableStartRowNo(ByRef sh As workSheet, ByRef startRowNo As Long, ByRef endRowNo As Long, ByRef tableDefineTitleColNo As Integer) As Long
    findNextTableStartRowNo = -1
    Dim r As Long
    With sh
        For r = startRowNo To endRowNo
            If .Cells(r, tableDefineTitleColNo) = tablePhyNameTitleContent Then
                findNextTableStartRowNo = r
                Exit Function
            End If
        Next
    End With
End Function

